package com.cnsugar.common.jdbc.dialect.db;

import com.cnsugar.common.jdbc.dialect.Dialect;

/**
 * 
 * Oracle的方言实现
 * 
 * @Author Sugar
 * @Version 2017年3月30日 下午6:34:38
 * @since JDK 1.5
 */
public class OracleDialect implements Dialect {
	public final static String NAME = "Oracle";
	private static OracleDialect instance;

	private OracleDialect() {
	}

	public static OracleDialect getInstance() {
		if (instance == null) {
			instance = new OracleDialect();
		}
		return instance;
	}

	@Override
	public boolean supportsLimit() {
		return true;
	}

	/**
	 * 将sql变成分页sql语句
	 * @param sql
	 *            实际SQL语句
	 * @param offset
	 *            分页开始纪录条数
	 * @param limit
	 *            分页纪录条数
	 * @return
	 */
	@Override
	public String getLimitString(String sql, int offset, int limit) {
		sql = sql.trim();
		boolean isForUpdate = false;
		if (sql.toLowerCase().endsWith(" for update")) {
			sql = sql.substring(0, sql.length() - 11);
			isForUpdate = true;
		}
		StringBuilder pagingSelect = new StringBuilder(sql.length() + 100);

		if (sql.startsWith("SELECT a.* FROM")) {
			pagingSelect.append("SELECT * FROM ( SELECT ROWNUM rownum_,").append(sql.substring(7));
			if (offset > 0) {
				pagingSelect.append(" ) TMP WHERE rownum_ <= ").append(offset+limit).append(" AND rownum_ > ").append(offset);
			} else {
				pagingSelect.append(" ) TMP WHERE rownum_ <= ").append(limit);
			}
		} else {
			if (offset > 0) {
				pagingSelect.append("SELECT * FROM ( SELECT row_.*, ROWNUM rownum_ FROM ( ");
			} else {
				pagingSelect.append("SELECT * FROM ( ");
			}
			pagingSelect.append(sql);
			if (offset > 0) {
				pagingSelect.append(" ) row_ WHERE ROWNUM <= ").append(offset+limit).append(") WHERE rownum_ > ").append(offset);
			} else {
				pagingSelect.append(" ) WHERE ROWNUM <= ").append(limit);
			}
		}
		if (isForUpdate) {
			pagingSelect.append(" for update");
		}

		return pagingSelect.toString();
	}

	@Override
	public String getDatabseProductName() {
		return NAME;
	}

	@Override
	public String getMark() {
		return "\"";
	}
}
